package codeGeneration;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.Scanner;

import parser.LogoProgram;

/**
 * Handles ensuring the LogoProgram could create a valid PostScript file Then
 * outputs all the postscript (including utility code) to the specified
 * PrintStream
 */
public class CodeGenerator {
	PrintWriter stream;

	// pass in Abstract Syntax Tree
	public CodeGenerator(PrintWriter out) {
		this.stream = out;
	}

	/**
	 * Checks the passed LogoProgram would be valid, and then prints the
	 * PostScript to the specified PrintWriter
	 * 
	 * @param LogoProgram
	 * @throws CodeGenerationException - If an error occurs. Print e.getMessage and exit.
	 */
	public void generateCode(LogoProgram program)
			throws CodeGenerationException {

		// Every program must have an entry point
		if (!program.containsMainFunction()) {
			throw new CodeGenerationException("Fatal Error: compiled program contains no entry point. Add a MAIN(VOID) function to the program.");
		}

		// Utility functions
		try {
			outputCommandFunctions();
		} catch (FileNotFoundException e) {
			throw new CodeGenerationException("Fatal Error: Unable to load LOGO Postscript utility functions in file " + e.getMessage());
		}

		// Generate the PostScript for the LOGO code
		program.generatePostScriptCode(stream);

		// Call the entry point
		stream.println("MAIN");

		// Must tell PostScript to draw the line strokes
		stream.println("stroke");

		stream.println("showpage");
	}

	// Output the left, right and forward postscript functions which we wrote
	// and are stored externally
	private void outputCommandFunctions() throws FileNotFoundException {
		// Quick way to read the whole file into the stream.
		// This file stores the left, right and forward functions in postscript
		Scanner scan = new Scanner(new File("logo_util.ps"));
		stream.println(scan.useDelimiter("\\Z").next());
		scan.close();
	}
}
